///////////////////////////////////////////////////////////////////////////////

#ifndef _SERVERBATTLEFIELD_H_
#include "serverbattlefield.h"
#endif

#ifndef _PHYSICS_H_
#include "physics.h"
#endif

///////////////////////////////////////////////////////////////////////////////


ServerBattlefield::ServerBattlefield()
{
    m_PhysicsEngine = Physics::GetPhysicalEngine();

    PE::Point wp(200, 200);
    m_Walls.push_back(Wall(1));
    m_Walls.back().SetPosition(wp);
    m_PhysicsEngine->AddObject(&m_Walls.back());
}


///////////////////////////////////////////////////////////////////////////////


ServerBattlefield::~ServerBattlefield()
{
}


///////////////////////////////////////////////////////////////////////////////


void ServerBattlefield::Update( size_t _dt )
{
    ProcessUserInput(_dt);
    m_PhysicsEngine->Update(_dt);
    DestroyBullets();
}


///////////////////////////////////////////////////////////////////////////////


void ServerBattlefield::ProcessUserInput( size_t _dt )
{
    // Process shooting
    for (PlayersList::iterator it = m_Players.begin(); it != m_Players.end(); ++it)
    {
        it->ProcessInput(_dt);

        Bullet* bullet = it->PullTheTrigger();

        if (bullet)
        {
            m_Bullets.push_back(*bullet);
            m_PhysicsEngine->AddObject( &m_Bullets.back() );
            delete bullet;
        }
    }
}


///////////////////////////////////////////////////////////////////////////////


void ServerBattlefield::DestroyBullets()
{
    // Delete destroyed bullets
    BulletsList::iterator it = m_Bullets.begin();
    while ( it != m_Bullets.end() )
    {
        if ( it->IsDestroyed() )
        {
            m_PhysicsEngine->DeleteObject(&*it);
            it = m_Bullets.erase(it);
        }
        else
            ++it;
    }    
}


///////////////////////////////////////////////////////////////////////////////


void ServerBattlefield::AddPlayer( int _ID )
{
    Player player(_ID);
    m_Players.push_back(player);
    m_PhysicsEngine->AddObject( &m_Players.back() );
}


///////////////////////////////////////////////////////////////////////////////


void ServerBattlefield::SetClientInput( int _clientID,
                                        const ClientInput& _input,
                                        size_t _creationTime )
{
    Player* player = FindPlayer(_clientID);
    if (player)
        player->SetClientInput(_input, _creationTime);
}


////////////////////////////////////////////////////////////////////////////////


ServerState ServerBattlefield::GetState() const
{
    return ServerState( GetPlayers(), GetBullets(), GetWalls() );
}


////////////////////////////////////////////////////////////////////////////////


Player* ServerBattlefield::FindPlayer( int _ID )
{
    PlayersList::iterator it = m_Players.begin();
    while ( it != m_Players.end() )
    {
        if ( it->GetID() == _ID )
        {
            return &*it;
        }
    }

    return NULL;
}


////////////////////////////////////////////////////////////////////////////////


void ServerBattlefield::RemovePlayer( int _ID )
{
    PlayersList::iterator it = m_Players.begin();
    while ( it != m_Players.end() )
    {
        if ( it->GetID() == _ID )
        {
            m_Players.erase(it);
            return;
        }
    }
}


////////////////////////////////////////////////////////////////////////////////
